package com.xh.rufongwallpaper.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xh.rufongwallpaper.common.constant.Constants;
import com.xh.rufongwallpaper.common.result.Result;
import com.xh.rufongwallpaper.common.util.VOConverter;
import com.xh.rufongwallpaper.config.UploadConfig;
import com.xh.rufongwallpaper.entity.Wallpaper;
import com.xh.rufongwallpaper.service.DownloadService;
import com.xh.rufongwallpaper.service.WallpaperService;
import com.xh.rufongwallpaper.vo.PageResponseVO;
import com.xh.rufongwallpaper.vo.WallpaperVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Optional;

/**
 * 壁纸控制器
 *
 * @author XH
 */
@Slf4j
@RestController
@RequestMapping("/wallpapers")
@RequiredArgsConstructor
@Tag(name = "壁纸API", description = "壁纸查询、下载等接口")
public class WallpaperController {

    private final WallpaperService wallpaperService;
    private final DownloadService downloadService;
    private final UploadConfig uploadConfig;

    /**
     * 获取壁纸列表
     */
    @GetMapping
    @Operation(summary = "获取壁纸列表", description = "分页获取壁纸列表，支持排序和分类过滤")
    public PageResponseVO<WallpaperVO> getWallpapers(
            @Parameter(description = "页码，从1开始") @RequestParam(defaultValue = "1") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") int limit,
            @Parameter(description = "排序方式：popular-热门，newest-最新，trending-趋势") 
            @RequestParam(defaultValue = "popular") String sort,
            @Parameter(description = "分类ID") 
            @RequestParam(required = false) Long category) {
        
        // 将页码转为0-based索引
        int pageIndex = Math.max(0, page - 1);
        int pageSize = Math.min(limit, Constants.MAX_PAGE_SIZE);
        
        Page<Wallpaper> wallpaperPage;
        
        // 根据排序方式和分类筛选
        if (category != null) {
            wallpaperPage = wallpaperService.getWallpapersByCategory(category, pageIndex, pageSize);
        } else {
            switch (sort) {
                case "newest":
                    wallpaperPage = wallpaperService.getLatestWallpapers(pageIndex, pageSize);
                    break;
                case "trending":
                    wallpaperPage = wallpaperService.getTrendingWallpapers(pageIndex, pageSize);
                    break;
                case "popular":
                default:
                    wallpaperPage = wallpaperService.getHotWallpapers(pageIndex, pageSize);
                    break;
            }
        }
        
        // 转换为前端响应格式
        return VOConverter.convertToPageResponse(wallpaperPage);
    }

    /**
     * 搜索壁纸
     */
    @GetMapping("/search")
    @Operation(summary = "搜索壁纸", description = "根据关键词搜索壁纸")
    public PageResponseVO<WallpaperVO> searchWallpapers(
            @Parameter(description = "关键词") @RequestParam String keyword,
            @Parameter(description = "页码，从1开始") @RequestParam(defaultValue = "1") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") int limit) {
        
        // 将页码转为0-based索引
        int pageIndex = Math.max(0, page - 1);
        int pageSize = Math.min(limit, Constants.MAX_PAGE_SIZE);
        
        Page<Wallpaper> wallpaperPage = wallpaperService.searchWallpapers(keyword, pageIndex, pageSize);
        
        // 转换为前端响应格式
        return VOConverter.convertToPageResponse(wallpaperPage);
    }
    
    /**
     * 获取壁纸详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取壁纸详情", description = "根据ID获取壁纸详情")
    public Result<WallpaperVO> getWallpaperDetail(
            @Parameter(description = "壁纸ID") @PathVariable Long id) {
        
        return wallpaperService.getWallpaperById(id)
                .map(wallpaper -> Result.success(VOConverter.convertToWallpaperVO(wallpaper)))
                .orElse(Result.failure("壁纸不存在"));
    }
    
    /**
     * 根据标签获取壁纸
     */
    @GetMapping("/tags/{tag}")
    @Operation(summary = "根据标签获取壁纸", description = "获取包含指定标签的壁纸")
    public PageResponseVO<WallpaperVO> getWallpapersByTag(
            @Parameter(description = "标签") @PathVariable String tag,
            @Parameter(description = "页码，从1开始") @RequestParam(defaultValue = "1") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") int limit) {
        
        // 将页码转为0-based索引
        int pageIndex = Math.max(0, page - 1);
        int pageSize = Math.min(limit, Constants.MAX_PAGE_SIZE);
        
        Page<Wallpaper> wallpaperPage = wallpaperService.getWallpapersByTag(tag, pageIndex, pageSize);
        
        // 转换为前端响应格式
        return VOConverter.convertToPageResponse(wallpaperPage);
    }
    
    @GetMapping("/random")
    @Operation(summary = "获取随机壁纸", description = "随机获取一张壁纸")
    public Result<WallpaperVO> getRandomWallpaper(
            @Parameter(description = "分类ID") @RequestParam(required = false) Long category) {
        
        Wallpaper randomWallpaper = wallpaperService.getRandomWallpaper(category);
        if (randomWallpaper == null) {
            return Result.failure("未找到符合条件的壁纸");
        }
        
        return Result.success(VOConverter.convertToWallpaperVO(randomWallpaper));
    }

    /**
     * 下载壁纸
     */
    @GetMapping("/download/{id}")
    @Operation(summary = "下载壁纸", description = "记录壁纸下载，并增加下载次数")
    public void downloadWallpaper(
            @Parameter(description = "壁纸ID") @PathVariable Long id,
            @Parameter(description = "设备ID") @RequestHeader(value = "X-Device-ID", required = false) String deviceId,
            HttpServletResponse response) {

        try {
            Optional<Wallpaper> wallpaper = wallpaperService.getWallpaperById(id);
            if (wallpaper.isEmpty()) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "壁纸不存在");
                return;
            }
            Wallpaper paper = wallpaper.get();

            // 获取绝对路径
            File file = new File(uploadConfig.getBasePath(), paper.getFilePath());
            if (!file.exists()) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "壁纸文件不存在");
                return;
            }

            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=" + paper.getTitle() + ".jpg");

            // 读取文件并写入响应
            try (InputStream inputStream = new FileInputStream(file);
                 OutputStream outputStream = response.getOutputStream()) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
            }
        } catch (IOException e) {
            log.error("下载壁纸失败: id={}", id, e);
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "下载壁纸失败");
            } catch (IOException ex) {
                log.error("发送错误响应失败", ex);
            }
        }
    }


    /**
     * 加载壁纸图片
     *
     * @param id 壁纸ID
     * @param response HTTP响应
     */
    @GetMapping("/image/{id}")
    @Operation(summary = "加载壁纸图片", description = "根据壁纸ID加载壁纸图片")
    public void loadWallpaperImage(
            @Parameter(description = "壁纸ID") @PathVariable Long id,
            HttpServletResponse response) {
        try {
            // 获取壁纸文件路径
            String relativePath = wallpaperService.getWallpaperFilePath(id);
            if (relativePath == null) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "壁纸不存在");
                return;
            }

            // 获取绝对路径
            File file = new File(uploadConfig.getBasePath(), relativePath);
            if (!file.exists()) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "壁纸文件不存在");
                return;
            }

            // 设置响应头
            response.setContentType("image/jpeg");
            response.setHeader("Cache-Control", "public, max-age=31536000"); // 缓存1年

            // 读取文件并写入响应
            try (InputStream inputStream = new FileInputStream(file);
                 OutputStream outputStream = response.getOutputStream()) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
            }
        } catch (IOException e) {
            log.error("加载壁纸图片失败: id={}", id, e);
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "加载壁纸失败");
            } catch (IOException ex) {
                log.error("发送错误响应失败", ex);
            }
        }
    }

    /**
     * 加载壁纸缩略图
     *
     * @param id 壁纸ID
     * @param response HTTP响应
     */
    @GetMapping("/thumbnail/{id}")
    @Operation(summary = "加载壁纸缩略图", description = "根据壁纸ID加载壁纸缩略图")
    public void loadWallpaperThumbnail(
            @Parameter(description = "壁纸ID") @PathVariable Long id,
            HttpServletResponse response) {
        try {
            // 获取壁纸缩略图文件路径
            String relativePath = wallpaperService.getWallpaperThumbnailPath(id);
            if (relativePath == null) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "壁纸缩略图不存在");
                return;
            }

            // 获取绝对路径
            File file = new File(uploadConfig.getBasePath(), relativePath);
            if (!file.exists()) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "壁纸缩略图文件不存在");
                return;
            }

            // 设置响应头
            response.setContentType("image/jpeg");
            response.setHeader("Cache-Control", "public, max-age=31536000"); // 缓存1年

            // 读取文件并写入响应
            try (InputStream inputStream = new FileInputStream(file);
                 OutputStream outputStream = response.getOutputStream()) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
            }
        } catch (IOException e) {
            log.error("加载壁纸缩略图失败: id={}", id, e);
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "加载壁纸缩略图失败");
            } catch (IOException ex) {
                log.error("发送错误响应失败", ex);
            }
        }
    }
} 